package com.hcbd.tdwt.util;



import com.hcbd.tdwt.ui.xingyu.vo.Position;
import com.hcbd.tdwt.ui.xingyu.vo.PositionVo;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * - @Description:  数据转换类
 * - @Author:  LXJ
 * - @Time:  2019/4/24 15:03
 */
public class ConvertData {
    private static final String Charset = "UTF-8";
    public static final String GB18030 = "GB18030";
    public static final String ISO8859_1 = "ISO-8859-1";
    /**
     * 二进制字符串转十六进制字符串
     * @param
     * @return
     */
    public static String bit2Hex(String bits){
        StringBuilder sb = new StringBuilder();
        int len = bits.length();

        for (int i = 0; i < len / 4; i++){
            //每4个二进制位转换为1个十六进制位
            String temp = bits.substring(i * 4, (i + 1) * 4);
            int tempInt = Integer.parseInt(temp, 2);
            String tempHex = Integer.toHexString(tempInt).toUpperCase();
            sb.append(tempHex);
        }
        return sb.toString();
    }
    /**
     * 截取对应长度--不足前面补0
     * @param value
     * @param len
     * @return
     */
    public static String toLength(String value, int len){
        String str = value;
        if (str.length() > len){
            return str.substring(str.length()-len);
        }else {
            while (str.length() != len){
                str = "0"+str;
            }
        }
        return str;
    }

    /**
     * 十六进制字符串转二进制字符串
     * @param hex
     * @return
     */
    public static String Hex2Bit(String hex){
        StringBuilder sb = new StringBuilder();
        int len = hex.length();

        for (int i = 0; i < len; i++){
            //每1个十六进制位转换为4个二进制位
            String temp = hex.substring(i, i + 1);
            int tempInt = Integer.parseInt(temp, 16);
            String tempBin = Integer.toBinaryString(tempInt);
            //如果二进制数不足4位，补0
            if (tempBin.length() < 4){
                int num = 4 - tempBin.length();
                for (int j = 0; j < num; j++){
                    sb.append("0");
                }
            }
            sb.append(tempBin);
        }
        return sb.toString();
    }

    /**
     * 获取byte的值，范围是0~255
     *
     * @param b
     * @return
     */
    public static int getByteValue(byte b) {
        return b & 0xff;
    }

    public static byte int2Byte(int intData) {
        return (byte) intData;
    }

    /**
     * <p>
     * short转byte[],数组从左到右，高位到低位
     * </p>
     * 由于java没有unsigned类型，所以用int存short的值
     *
     * @param shortData
     * @return byte[]:byteData
     */
    public static byte[] short2bytes(int shortData) {
        byte[] byteData = new byte[2];
        for (int i = 0; i < 2; i++) {
            int offset = i * 8;
            byteData[i] = (byte) (shortData >> offset);
        }
        reversalBytes(byteData);
        return byteData;
    }

    /**
     * int转byte[],数组从左到右，数组从左到右，高位到低位
     *
     * @param intData
     * @return byte[]:byteData
     */
    public static byte[] int2bytes(int intData) {
        byte[] byteData = new byte[4];
        for (int i = 0; i < 4; i++) {
            int offset = i * 8;
            byteData[i] = (byte) (intData >> offset);
        }
        reversalBytes(byteData);
        return byteData;
    }

    /**
     * long转byte[],数组从左到右，数组从左到右，高位到低位
     *
     * @param longData
     * @return byte[]:byteData
     */
    public static byte[] long2bytes(long longData) {
        byte[] byteData = new byte[8];
        for (int i = 0; i < 8; i++) {
            int offset = i * 8;
            byteData[i] = (byte) (longData >> offset);
        }
        reversalBytes(byteData);
        return byteData;
    }
    public static short[] toShortArray(byte[] src) {

        int count = src.length >> 1;
        short[] dest = new short[count];
        ByteBuffer.wrap(src).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(dest);
//        for (int i = 0; i < count; i++) {
//            dest[i] = (short) (src[i * 2] << 8 | src[2 * i + 1] & 0xff);
//        }
        return dest;
    }

    public static byte[] toByteArray(short[] src) {

        int count = src.length;
        byte[] dest = new byte[count << 1];
        ByteBuffer.wrap(dest).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(src);
//        for (int i = 0; i < count; i++) {
//            dest[i * 2] = (byte) (src[i] >> 8);
//            dest[i * 2 + 1] = (byte) (src[i] >> 0);
//        }

        return dest;
    }
    /**
     * bytes转short,数组从左到右，依次是高位到低位
     *
     * @param bytes
     * @return short
     */
    public static short bytes2short(byte[] bytes) {
        short shortData = 0;
        int len = bytes.length <= 2 ? bytes.length : 2;
        for (int i = 0; i < len; i++) {
            shortData <<= 8;
            shortData |= (bytes[i] & 0xff);
        }
        return shortData;
    }

    /**
     * bytes转int,数组从左到右，依次是高位到低位
     *
     * @param bytes
     * @return int
     */
    public static int bytes2int(byte[] bytes) {
        int intData = 0;
        int len = bytes.length <= 4 ? bytes.length : 4;
        for (int i = 0; i < len; i++) {
            intData <<= 8;
            intData |= (bytes[i] & 0xff);
        }
        return intData;
    }

    /**
     * bytes中选取少于等4个字节转int
     *
     * @param bytes 包含int字节的数组
     * @param start int字节在数组中起始index
     * @param len   int字节长度 不可大于8
     * @return 如果起始start加上len大于bytes长度将返回-1
     */
    public static int bytes2int(byte[] bytes, int start, int len) {
        int intData = 0;
        int length = len <= 4 ? start + len : start + 4;
        if (length > bytes.length) {
            return -1;
        }
        for (int i = start; i < length; i++) {
            intData <<= 8;
            intData |= (bytes[i] & 0xff);
        }
        return intData;
    }

    /**
     * bytes转long
     *
     * @param bytes 数组从左到右，依次是高位到低位
     * @return long
     */
    public static long bytes2long(byte[] bytes) {
        long longData = 0;
        int len = bytes.length <= 8 ? bytes.length : 8;
        for (int i = 0; i < len; i++) {
            longData <<= 8;
            longData |= (bytes[i] & 0xff);
        }
        return longData;
    }

    /**
     * bytes中选取少于等8个字节转long
     *
     * @param bytes 包含long字节的数组
     * @param start long字节在数组中起始index
     * @param len   long字节长度 不可大于8
     * @return 如果起始start加上len大于bytes长度将返回-1
     */
    public static long bytes2long(byte[] bytes, int start, int len) {
        long longData = 0;
        int length = len <= 8 ? start + len : start + 8;
        if (length > bytes.length)
            return -1;
        for (int i = start; i < length; i++) {
            longData <<= 8;
            longData |= (bytes[i] & 0xff);
        }
        return longData;
    }

    /**
     * bytes转String
     *
     * @param bytes
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String bytes2string(byte[] bytes) {
        if (bytes == null) {
            return "";
        }
        String newStr = null;
        try {
            newStr = new String(bytes, GB18030).trim();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return newStr;
    }

    /**
     * bytes转String
     *
     * @param bytes
     * @param charset
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String bytes2string(byte[] bytes, String charset) {
        if (bytes == null) {
            return "";
        }
        String newStr = null;
        try {
            newStr = new String(bytes, charset).trim();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return newStr;
    }

    /**
     * bytes中指定子数组转String
     *
     * @param bytes
     * @param charset
     * @param start
     * @param len
     * @return
     */
    public static String bytes2string(byte[] bytes, String charset, int start, int len) {
        if (bytes == null) {
            return "";
        }
        if (start + len > bytes.length) {
            len = bytes.length - start;
        }
        String newStr = null;
        try {
            byte[] tmp = new byte[len];
            System.arraycopy(bytes, start, tmp, 0, len);
            newStr = new String(tmp, Charset).trim();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return newStr;
    }

    /**
     * String转bytes
     *
     * @param str
     * @return
     * @throws UnsupportedEncodingException
     */
    public static byte[] string2bytes(String str) throws UnsupportedEncodingException {
        if (str == null) {
            return null;
        }
        return str.getBytes(Charset);
    }

    /**
     * String转bytes
     *
     * @param str
     * @param charset
     * @return
     * @throws UnsupportedEncodingException
     */
    public static byte[] string2bytes(String str, String charset) throws UnsupportedEncodingException {
        if (str == null) {
            return null;
        }
        return str.getBytes(charset);
    }

    /**
     * 将byte转化成16进制的字符串 byte=10,String=0a
     *
     * @param b
     * @return String hex
     */
    public static String byte2hex(byte b) {
        int value = b & 0xff;
        String hexVaule = Integer.toHexString(value);
        if (hexVaule.length() < 2) {
            hexVaule = "0" + hexVaule;
        }
        return hexVaule;
    }

    /**
     * 将byte[]转化成16进制的字符串 byte[]=10,11,12,String=0a0b0c
     *
     * @param bytes
     * @return String hex
     */
    public static String bytes2hex(byte[] bytes) {
        String hex = "";
        for (int i = 0; i < bytes.length; i++) {
            int value = bytes[i] & 0xff;
            String hexVaule = Integer.toHexString(value);
            if (hexVaule.length() < 2) {
                hexVaule = "0" + hexVaule;
            }
            hex += hexVaule;
        }
        return hex;
    }

    /**
     * 将byte[] 指定子数组转化成16进制的字符串 byte[]=10,11,12,String=0a0b0c
     *
     * @param bytes
     * @param start 子数组起始位置
     * @param len   子数组长度
     * @return
     */
    public static String bytes2hex(byte[] bytes, int start, int len) {
        String hex = "";
        int length = start + len;
        if (length > bytes.length) {
            return hex;
        }

        for (int i = start; i < length; i++) {
            int value = bytes[i] & 0xff;
            String hexVaule = Integer.toHexString(value);
            if (hexVaule.length() < 2) {
                hexVaule = "0" + hexVaule;
            }
            hex += hexVaule;
        }
        return hex;
    }

    /**
     * byte[]=10,11,12,String=0a0b0c 将16进制的字符串转为byte数组，如果hex的长度不是偶数，则首位补0
     *
     * @param hex
     * @return
     */
    public static byte[] hex2bytes(String hex) {
        if (hex == null || hex.length() < 1) {
            return null;
        }

        // 如果长度不是偶数，则前面补0
        if (hex.length() % 2 != 0) {
            hex = "0" + hex;
        }

        byte[] bytes = new byte[(hex.length() + 1) / 2];

        try {
            for (int i = 0, j = 0; i < hex.length(); i += 2) {
                byte hight = (byte) (Character.digit(hex.charAt(i), 16) & 0xff);
                byte low = (byte) (Character.digit(hex.charAt(i + 1), 16) & 0xff);
                bytes[j++] = (byte) (hight << 4 | low);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        return bytes;
    }

    /**
     * byte[]转为坐标类型,先转为int，再除以10^6
     * <p>
     * 这里的坐标数据只支持4byte，坐标有正负数
     * </p>
     *
     * @param bytes
     * @return
     */
    public static double bytes2Coordinate(byte[] bytes) {
        double d = 0;
        long l = bytes2int(bytes);
        d = l / 1000000.0;
        return d;
    }

    /**
     * <p>
     * 将src的内容复制到dest中
     * </p>
     * <ul>
     * <li>如果src为null，则dest也为null</li>
     * <li>如果dest为null或者dest.length&lt;src.length，则dest=new byte[src.length]</li>
     * </ul>
     *
     * @param src  要复制的byte[]
     * @param dest 复制的目标byte[]
     */
    public static void copyBytes(byte[] src, byte[] dest) {
        if (src == null) {
            dest = null;
        }
        if (dest == null || dest.length < src.length) {
            dest = new byte[src.length];
        }
        System.arraycopy(src, 0, dest, 0, src.length);
    }

    /**
     * <p>
     * 将appendBytes追加到oldBytes后面
     * <ul>
     * <li>1.如果appendBytes为null，则直接返回oldBytes</li>
     * <li>2.如果oldBytes为null，则直接返回appendBytes</li>
     * </ul>
     * </p>
     *
     * @param oldBytes    原数据
     * @param appendBytes 需要追加的数据
     * @return
     */
    public static byte[] appendBytes(byte[] oldBytes, byte[] appendBytes) {
        if (appendBytes == null) {
            return oldBytes;
        }

        if (oldBytes == null) {
            return appendBytes;
        }

        int len = 0;
        // 计算合并后的长度
        len = oldBytes.length + appendBytes.length;
        // 申请合并后的内存空间
        byte[] bytes = new byte[len];
        System.arraycopy(oldBytes, 0, bytes, 0, oldBytes.length);
        System.arraycopy(appendBytes, 0, bytes, oldBytes.length, appendBytes.length);
        return bytes;
    }

    /**
     * 获得short类型数据的无符号值
     *
     * @param data
     * @return
     */
    public static int getUnsignedShort(short data) {
        return data & 0xffff;
    }

    /**
     * 获得int类型的unsigned值
     */
    public static long getUnsignedInt(int data) {
        return data & 0xffffffffl;
    }

    /**
     * 翻转byte数组
     *
     * @param bytes
     */
    public static void reversalBytes(byte[] bytes) {
        byte b = 0;
        int length = bytes.length;
        int half = length / 2;
        for (int i = 0; i < half; i++) {
            b = bytes[i];
            bytes[i] = bytes[length - 1 - i];
            bytes[length - 1 - i] = b;
        }
    }

    /**
     * 截取数据
     *
     * @param data  要截取的源数据
     * @param start 开始截取位置(包含该点数据)
     * @param end   截取结束位置(包含该点数据)
     * @return
     */
    public static byte[] getSubData(byte[] data, int start, int end) {
        int length = end - start + 1;
        return getDataSequence(data, start, length);
    }

    /**
     * 获取子串
     *
     * @param data  要获取子串的原始数据
     * @param start 开始位置，包含改节点
     * @param len   要截取的子串长度
     * @return
     */
    public static byte[] getDataSequence(byte[] data, int start, int len) {
        byte[] returnData = new byte[len];
        System.arraycopy(data, start, returnData, 0, len);
        return returnData;
    }

    /*******************************************(转为16进制)******************************************************/

    /**
     * string转16进制
     *
     * @return
     */
    public static String stringToHex(String str) {
        String hex;
        try {
            byte[] bytes = string2bytes(str, GB18030);
            hex = bytes2hex(bytes);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
        return hex;
    }

    /**
     * string转16进制
     *
     * @return
     */
    public static String stringToHex(String str, String charset) {
        String hex;
        try {
            byte[] bytes = string2bytes(str, charset);
            hex = bytes2hex(bytes);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
        return hex;
    }

    /**
     * long转16进制
     *
     * @param l
     * @return
     */
    public static String longToHex(long l) {
        String hex;
        byte[] bytes = long2bytes(l);
        hex = bytes2hex(bytes);
        return hex;
    }

    /**
     * int转16进制
     *
     * @param i
     * @return
     */
    public static String intToHex(int i) {
        String hex;
        byte[] bytes = int2bytes(i);
        hex = bytes2hex(bytes);
        return hex;
    }

    /**
     * 位置转16进制
     *
     * @param lon
     * @param lat
     * @param alt
     * @return
     */
    public static String positionToHex(double lon, double lat, double alt) {
        //经度
        Long longitude = Math.round(lon * 1.0E6);
        byte[] longitudeBytes = long2bytes(longitude);
        String longitudeHex = bytes2hex(longitudeBytes).substring(8);
        //纬度
        Long latitude = Math.round(lat * 1.0E6);
        byte[] latitudeBytes = long2bytes(latitude);
        String latitudeHex = bytes2hex(latitudeBytes).substring(8);
        //高度
        Long altitude = Math.round(alt);
        byte[] altitudeBytes = long2bytes(altitude);
        String altitudeHex = bytes2hex(altitudeBytes).substring(12);
        //返回16进制
        return longitudeHex + latitudeHex + altitudeHex;
    }

    /**
     * 位置转16进制
     *
     * @param position
     * @return
     */
    public static String positionToHex(Position position) {
        //经度
        Long longitude = Math.round(position.getLongitude() * 1.0E6);
        String longitudeHex = longToHex(longitude).substring(8);
        //纬度
        Long latitude = Math.round(position.getLatitude() * 1.0E6);
        String latitudeHex = longToHex(latitude).substring(8);
        //高度
        Long altitude = Math.round(position.getAltitude());
        String altitudeHex = longToHex(altitude).substring(12);
        //返回16进制
        return longitudeHex+latitudeHex+altitudeHex;
    }
    /**
     * 位置转16进制
     *
     * @param position
     * @return
     */
    public static String positionToHex(PositionVo position) {
        //经度
        Long longitude = Math.round(position.getLongitude() * 1.0E6);
        String longitudeHex = longToHex(longitude).substring(8);
        //纬度
        Long latitude = Math.round(position.getLatitude() * 1.0E6);
        String latitudeHex = longToHex(latitude).substring(8);
        //高度
        Long altitude = Math.round(position.getAltitude());
        String altitudeHex = longToHex(altitude).substring(12);
        //返回16进制
        return longitudeHex+latitudeHex+ altitudeHex;
    }
    /**
     * 位置转16进制
     *
     * @param position
     * @return
     */
    public static String positionVoToHex(PositionVo position) {
        String logHex=posDFMCoverHex(position.getLongitude());
        String latHex=posDFMCoverHex(position.getLatitude());
        String speedHex=ConvertData.intToHex((int)position.getSpeed()).substring(4);
        String bearingHex=ConvertData.intToHex((int)position.getBearing()).substring(4);
        return "45"+logHex+"4E"+latHex+speedHex+bearingHex+"01";
    }
    public static String posDFMCoverHex(double du){
        int du1 = (int) du;
        double tp = (du - du1) * 60;
        int fen = (int) tp;
        String miao = String.format("%.2f", Math.abs(((tp - fen) * 60)));
        String duHex=intToHex(du1).substring(6);
        String fenHex=intToHex(Math.abs(fen)).substring(6);
        String second[]=miao.split("\\.");
        String second1=intToHex(Integer.parseInt(second[0])).substring(6);
        String second2=intToHex(Integer.parseInt(second[1])).substring(6);
        return duHex+fenHex+second1+second2;
    }
    /**
     * 位置转16进制2
     *
     * @param position
     * @return
     */
    public static String positionToHex2(Position position) {
        //经度
        String longitudeHex ;
        if(position.getLongitude()==0.0){
            longitudeHex="FFFFFFFF";
        }else{
            Long longitude = Math.round(position.getLongitude() * 1.0E6);
            longitudeHex = longToHex(longitude).substring(8);
        }
        //纬度
        String latitudeHex;
        if(position.getLatitude()==0.0){
            latitudeHex="FFFFFFFF";
        }else{
            Long latitude = Math.round(position.getLatitude() * 1.0E6);
            latitudeHex = longToHex(latitude).substring(8);
        }
        //高度
        String altitudeHex;
        if(position.getAltitude()==0.0){
            altitudeHex="FFFF";
        }else{
            Long altitude = Math.round(position.getAltitude());
            altitudeHex = longToHex(altitude).substring(12);
        }
        //返回16进制
        return longitudeHex + latitudeHex + altitudeHex;
    }
    /*******************************************(16进制转为基本数据类型)******************************************************/

    /**
     * 16进制转int
     *
     * @param hex 16进制字符串
     * @return
     */
    public static int hexToInt(String hex) {
        byte[] bytes = hex2bytes(hex);
        return bytes2int(bytes);
    }

    /**
     * 16进制转换成Long类型
     *
     * @param hex
     * @return
     */
    public static long hexToLong(String hex) {
        byte[] bytes = hex2bytes(hex);
        return bytes2long(bytes);
    }

    /**
     * 16进制转String
     *
     * @param hex
     * @return
     */
    public static String hexToString(String hex) {
        byte[] bytes = hex2bytes(hex);
        return bytes2string(bytes);
    }

    /**
     * 16进制转String
     *
     * @param hex
     * @return
     */
    public static String hexToString(String hex, String charset) {
        byte[] bytes = hex2bytes(hex);
        return bytes2string(bytes,charset);
    }
    /**
     * 16进制转度分秒
     *
     * @param hex
     * @return
     */
    public static String hexToDegMinSeconds(String hex) {
        StringBuffer str=new StringBuffer();
        if(hex.length()==8){
            long spend=hexToLong(hex.substring(0,2));//度
            long minute=hexToLong(hex.substring(2,4));//分
            long second=hexToLong(hex.substring(4,6));//秒
            long second_0_1=hexToLong(hex.substring(6,8));//0.1秒
            str.append(spend);
            str.append("°");
            str.append(minute);
            str.append("'");
            str.append(second);
            str.append(".");
            str.append(second_0_1);
            str.append("″");
        }
        return str.toString();
    }

}
